Consider a website representing lawyers: each lawyer’s profile page should list the practice areas to which they belong, but it must also be possible to browse lawyers for a given practice areas. In an XML repository, the lawyer items must reference the practice items and/or the practice items must reference the lawyer items. With a small data set it is possible to iterate over all of the data and filter the results (for instance, iterate over all lawyers to find those referencing a given practice area), but this could affect performance when data volume is larger. Sitecore’s links database can be useful for maintaining bidirectional relationships between items in the content management repository.
1. Overview
Sitecore maintains a table named Links in the database specified in the LinkDatabase section of web.config. This table provides a logical links database for all other databases – the links tables in the other databases are empty by default. Data is exposed through the Sitecore.Links.ItemLink class.
No matter how many databases are processed to create the links database, all entries are stored in a single table in the database specified by the following section of web.config:
<LinkDatabase type="Sitecore.Data.$(database).$(database)LinkDatabase, Sitecore.$(database)">
<param desc="connection" ref="connections/core">
</param>
</LinkDatabase>
The default is to store all entries in the core database, but for instance in a runtime web would probably be specified instead as the core database may not be enabled in a content delivery environment.
The template for the lawyer items will contain a multilist field named practices with its source property set to the parent of the practice areas (/sitecore/content/home/practices). XSL code rendering links to the practice areas for a lawyer is relatively straightforward; sc:item is used to look up the each of the pipe-separated GUIDs in the practices field and <sc:link> is called for each. Providing links to all lawyers for a practice area requires using the descendants axis or a custom XSL Extension is used to expose the links database.
The sample rendering code will work on both lawyer and practice area pages - on a lawyer page it will list the related practice areas; on a practice area page it will list related lawyers using three methods – the standard .NET descendants axis, the faster Sitecore XSL Extension Function sc:descendants() and the links database.
2. Installation
The package is provided as a simple example; as it may overwrite various Sitecore items it should only be installed on clean Sitecore instances.
Go to Downloads section to download the sample package for this article.
To register the XSL Extension, add the following to the <xslExtensions> section of /web.config, where “LawyerPractices.Xml.Xsl.XslUtil” is the fully qualified .NET class name (namespace.classname), “LawyerPractices” is the name of the .NET assembly containing that class and “http://www.sitecore.net/lp” is an arbitrary but unique URL (see http://sdn.sitecore.net/Articles/XSL/Using%20XSL%20Extension%20Objects.html):
<extension mode="on" type="LawyerPractices.Xml.Xsl.XslUtil, LawyerPractices" namespace="http://www.sitecore.net/lp" singleInstance="true" />
Perform a full publish in all languages, then rebuild the master and web links databases by choosing Sitecore > Control Panel > Database > Rebuild link database.
3. Caveats
As of Sitecore 5.1.1.15 (April 2006), the links database is maintained for fields of the following types:
- Checklist
- InternalLink
- Lookup
- Multilist
But not the following:
- Tree
- Treelist
Note: Treelist isn’t supported in 5.1/5.2, but is in 5.3 and later.
The order of references is controlled in the multilist (the user can order practices for a lawyer), but the default ordering in other views is XML document order.
Rebuilding the Links Database
Sitecore will generally manage the links database for the master database but it may be necessary to rebuild the link database for the web and possibly other databases periodically such as on publication. Adding the following handler to the end of the publish:end event defined in /web.config will cause the links database for the web database to be rebuilt after each publication, which could have an impact on performance, where “LawyerPractices.WebLinkDatabaseRebuilder” is the fully qualified .NET class name (namespace.classname), “LawyerPractices” is the name of the .NET assembly containing that class and “Process” is the name of the method to invoke in that class:
<handler type="LawyerPractices.WebLinkDatabaseRebuilder, LawyerPractices" method="Process" />
If the links database does not need to be rebuilt on every publication a System/Tasks/Command can be created under the Publish action for a specific workflow:
Whenever this workflow completes it will first publish, then rebuild the links database.
Another option would be rebuilding the links database with a scheduled process. This would require an entry such as the following in /web.config:
<agent type="LawyerPractices.WebLinkDatabaseRebuilder, LawyerPractices" method="Process" interval="24:00:00" />